package com.codemonkey.lq.extend.excelverification.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.codemonkey.lq.common.util.StringHelper;
import com.codemonkey.lq.extend.excelverification.AbstractVerifier;
import com.codemonkey.lq.extend.excelverification.CellContext;
import com.codemonkey.lq.extend.excelverification.spi.Continuable;

/*
 * 类型验证
 * 
 * */
public class TypeVerifier {

	public static class StringVerifier extends AbstractVerifier implements Continuable {

		@Override
		protected boolean doVerify(CellContext cellContext) {
			if (null == cellContext.getCellVal()) {
				cellContext.setCellVal("");
			} else {
				cellContext.setCellVal(cellContext.getCellVal().toString());
			}

			return true;
		}

		@Override
		public String getReadableFailMsg(CellContext cellContext) {
			return "";
		}

		@Override
		public boolean isContinue(CellContext cellContext) {
			// 任何时候都继续, 皆为String
			return true;
		}

	}

	public static class IntegerVerifier extends AbstractVerifier implements Continuable {
		private boolean isPass;

		@Override
		protected boolean doVerify(CellContext cellContext) {
			Exception ex = null;
			try {
				Integer.parseInt(cellContext.getCellVal().toString());
			} catch (Exception e) {
				ex = e;
			}

			if (null != ex) {
				StringBuilder sb = new StringBuilder("###TypeVerifier[ ");
				sb.append(this.getClass().getSimpleName()).append(" ]").append(
						System.lineSeparator());

				commonConstructFailContextInfo(cellContext, sb);

				cellContext.addException(ex);
				cellContext.addErrorMsg(sb.toString());

				isPass = false;

			} else {
				cellContext.setCellVal(Integer.parseInt(cellContext.getCellVal().toString()));
				isPass = true;
			}

			return isPass;
		}

		@Override
		public String getReadableFailMsg(CellContext cellContext) {
			return String.format(" [ %s ] must be a int.", cellContext.getCellName());
		}

		@Override
		public boolean isContinue(CellContext cellContext) {
			// 验证通过就继续
			return isPass;
		}
	}

	public static class FloatVerifier extends AbstractVerifier implements Continuable {
		private boolean isPass;

		@Override
		protected boolean doVerify(CellContext cellContext) {
			Exception ex = null;
			try {
				Float.parseFloat(cellContext.getCellVal().toString());
			} catch (Exception e) {
				ex = e;
			}

			if (null != ex) {
				StringBuilder sb = new StringBuilder("###TypeVerifier[ ");
				sb.append(this.getClass().getSimpleName()).append(" ]").append(
						System.lineSeparator());

				commonConstructFailContextInfo(cellContext, sb);

				cellContext.addException(ex);
				cellContext.addErrorMsg(sb.toString());

				isPass = false;
			} else {
				cellContext.setCellVal(Float.parseFloat(cellContext.getCellVal().toString()));
				isPass = true;
			}

			return isPass;
		}

		@Override
		public String getReadableFailMsg(CellContext cellContext) {
			return String.format(" [ %s ] must be a float.", cellContext.getCellName());
		}

		@Override
		public boolean isContinue(CellContext cellContext) {
			// 验证通过就继续
			return isPass;
		}
	}

	public static class DateVerifier extends AbstractVerifier implements Continuable {

		private boolean isPass;

		private final String pattern;

		private DateVerifier() {
			this("yyyy-MM-dd");
		}

		private DateVerifier(String pattern) {
			this.pattern = pattern;
		}

		public static DateVerifier of(String pattern) {
			return (StringHelper.isEmpty(pattern) ? new DateVerifier() : new DateVerifier(pattern));
		}

		@Override
		protected boolean doVerify(CellContext cellContext) {
			final Object cellVal = cellContext.getCellVal();
			if(cellVal instanceof java.util.Date){
				return true;
			}
			
			Exception ex = null;
			try {
				(new SimpleDateFormat(pattern)).parse(cellVal.toString());
			} catch (Exception e) {
				ex = e;
			}

			if (null != ex) {
				StringBuilder sb = new StringBuilder("###TypeVerifier[ ");
				sb.append(this.getClass().getSimpleName()).append(" ]").append(
						System.lineSeparator());

				commonConstructFailContextInfo(cellContext, sb);

				cellContext.addException(ex);
				cellContext.addErrorMsg(sb.toString());

				isPass = false;
			} else {
				// 上面已经验证过了
				try {
					cellContext.setCellVal((new SimpleDateFormat(pattern)).parse(pattern));
				} catch (ParseException e) {
				}

				isPass = true;
			}

			return isPass;
		}

		@Override
		public String getReadableFailMsg(CellContext cellContext) {
			return String.format(" [ %s ] must be a date type.", cellContext.getCellName());
		}

		@Override
		public boolean isContinue(CellContext cellContext) {
			// 验证通过就继续
			return isPass;
		}
	}

	public static class BooleanVerifier extends AbstractVerifier implements Continuable {

		private boolean isPass;

		/**
		 * 代表true的flag集合; 例如1,true等等
		 */
		private List<String> truFlagList = new ArrayList<String>();

		private BooleanVerifier(String trueFlags) {
			String[] split = trueFlags.split(";");
			truFlagList = Arrays.asList(split);
		}

		public static BooleanVerifier of(String trueFlags) {
			return new BooleanVerifier(trueFlags);
		}

		@Override
		protected boolean doVerify(CellContext cellContext) {
			String cellVal = cellContext.getCellVal().toString();
			final boolean isTrue = truFlagList.indexOf(cellVal) >= 0;
			if (isTrue) {
				cellContext.setCellVal(true);
				isPass = true;
			} else {
				StringBuilder sb = new StringBuilder("###TypeVerifier[ ");
				sb.append(this.getClass().getSimpleName()).append(" ]").append(
						System.lineSeparator());

				commonConstructFailContextInfo(cellContext, sb);

				cellContext.addErrorMsg(sb.toString());

				isPass = false;
			}

			return isPass;
		}

		@Override
		public String getReadableFailMsg(CellContext cellContext) {
			return String.format(" [ %s ] must be a boolean type.", cellContext.getCellName());
		}

		@Override
		public boolean isContinue(CellContext cellContext) {
			// 验证通过就继续
			return isPass;
		}

	}
}
